package com.xiaocz.hblsubstitutedriving.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.xiaocz.common.Common;
import com.xiaocz.common.http.AsyncHttpPostFormData;
import com.xiaocz.common.http.AsyncHttpResponse;
import com.xiaocz.common.http.AsyncOkHttpClient;
import com.xiaocz.common.http.AsyncResponseHandler;
import com.xiaocz.common.model.RspModel;
import com.xiaocz.common.utils.AccountManagers;
import com.xiaocz.hblsubstitutedriving.App;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

@SuppressLint("SdCardPath")
public class CrashHandler implements UncaughtExceptionHandler {

    static final String PATH = Environment.getExternalStorageDirectory().getPath() + "/ZJR/error/";
    private static final String TAG = "CrashHandler";
    static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CANADA);
    private static CrashHandler mInstance = new CrashHandler();
    private Context mContext;

    private Thread.UncaughtExceptionHandler mDefaultCrashHandler;

    public static CrashHandler getInstance() {
        return mInstance;
    }

    public void init(Context context) {
        mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
        mContext = context.getApplicationContext();
    }

    /**
     * 关键函数,当程序中有未捕获的异常,系统将自动调用uncaughtException,
     *
     * @param thread    未捕获异常的线程
     * @param throwable throwable为未捕获的异常
     */

    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        //把异常信心写到sdcard
        dumpExceptionToSDcard(throwable);
        //打印堆栈
        throwable.printStackTrace();
        //如果系统提供了默认的处理器,交给系统处理,否则kill掉自己
        if (mDefaultCrashHandler != null) {
            mDefaultCrashHandler.uncaughtException(thread, throwable);
        }
    }

    // 读文件
    public void readTxt() {
        File dir = new File(PATH + "error.log");
        if (dir.exists()) {
            try {
                FileInputStream mFile = new FileInputStream(dir);
                BufferedReader reader = new BufferedReader(new InputStreamReader(mFile,
                        StandardCharsets.UTF_8)); // 指定读取文件的编码格式，要和写入的格式一致，以免出现中文乱码,
                String str;
                StringBuilder builder = new StringBuilder();
                while ((str = reader.readLine()) != null) {
                    builder.append(str);
                    builder.append("---------;\n");
                }
                onUploadLog(builder.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void dumpExceptionToSDcard(Throwable throwable) {
        //判断SD卡不存在或无法使用
        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            return;
        }
        File dir = new File(PATH);
        if (!dir.exists()) {
            boolean isSuccess = dir.mkdir();
        }
        File file = new File(PATH + "error.log");
        try {
            PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter(file)));
            printWriter.println(simpleDateFormat.format(new Date(System.currentTimeMillis())));
            dumpDeviceInfo(printWriter);
            throwable.printStackTrace(printWriter);
            printWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void dumpDeviceInfo(PrintWriter printWriter) throws PackageManager.NameNotFoundException {
        PackageManager packageManager = mContext.getPackageManager();
        PackageInfo packageInfo = packageManager.getPackageInfo(mContext.getPackageName(), packageManager.GET_ACTIVITIES);
        //print app version
        printWriter.println("App Version: " + packageInfo.versionName + "_" + packageInfo.versionCode);
        //print android version
        printWriter.println("Android OS Version: " + Build.VERSION.RELEASE + "_" + Build.VERSION.SDK_INT);
        //print Maker
        printWriter.println("Maker: " + Build.MANUFACTURER);
        //print mode
        printWriter.println("Mode: " + Build.MODEL);
        //print CPU ABI
        printWriter.println("CPU API: " + Build.CPU_ABI);
    }

    /**
     * 上传错误信息
     */
    private void onUploadLog(String logTxt) {
        AsyncOkHttpClient okHttpClient = new AsyncOkHttpClient();
        AsyncHttpPostFormData asyncHttpPostFormData = new AsyncHttpPostFormData();
        asyncHttpPostFormData.addFormData("driver_id", AccountManagers.getUserId());
        asyncHttpPostFormData.addFormData("OSVersion", getVersionCode());
        asyncHttpPostFormData.addFormData("mobileModel", Build.MODEL);
        asyncHttpPostFormData.addFormData("logtxt", logTxt);
        okHttpClient.post(Common.Constant.API_IP + "api/Common/uploadErrorLog", asyncHttpPostFormData, new AsyncResponseHandler() {
            @Override
            public void onFailure(IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onSuccess(AsyncHttpResponse response) {
                Type type = new TypeToken<RspModel<String>>() {
                }.getType();
                RspModel<String> rspModel = new Gson().fromJson(response.getBody(), type);
                if (rspModel == null) {
                    return;
                }
                switch (rspModel.getCode()) {
                    case 200:
                        if (rspModel.isStatus()) {//保存用户
                            File path = new File(PATH + "error.log");
                            boolean delete = path.delete();
                            if (delete) {
                                System.out.println("---r删除成功");
                            }
                        } else {
                            App.getInstance().showMessage(rspModel.getMessage());
                        }
                        break;
                    default:
                        App.getInstance().showMessage(rspModel.getMessage());
                        break;
                }
            }
        });
    }

    /*
     * 获取当前程序的版本号
     */
    private String getVersionCode() {
        PackageManager packageManager = mContext.getPackageManager();
        try {
            PackageInfo packageInfo = packageManager.getPackageInfo(mContext.getPackageName(), packageManager.GET_ACTIVITIES);
            return packageInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return "获取失败";
    }
}